function Point(x, y, prev = null) {
    this.x = x;
    this.y = y;
    this.prev = prev;
}

function solve(map, miner, exit) {
    console.log(map, miner, exit)
    var grid = map[0].map((v, i) => map.map(v => v[i]));
    var X = grid.length, Y = grid[0].length;
    var boundCheck = (x, y) => x > -1 && x < X && y > -1 && y < Y;
    var visited = grid.map(v => v.map(e => false));
    var moves = [[0, -1], [0, 1], [-1, 0], [1, 0]];
    var st = new Point(miner.y, miner.x);
    var queue = [st];
    visited[st.x][st.y] = true;
    var head = null;
    while (queue.length) {
        var curr = queue.shift();
        if (curr.x === exit.y && curr.y === exit.x) {
            console.log('miner reach exit.');
            head = curr;
            break;
        }
        for (mov of moves) {
            var x = curr.x + mov[0], y = curr.y + mov[1];
            if (boundCheck(x, y) && !visited[x][y] && grid[x][y]) {
                visited[x][y] = true;
                queue.push(new Point(x, y, curr))
            }
        }
    }
    var directions = { '1,0': 'down', '-1,0': 'up', '0,-1': 'left', '0,1': 'right' }
    var path = []
    while (head.prev) {
        var prev = head.prev;
        var k = `${head.x - prev.x},${head.y - prev.y}`;
        path.unshift(directions[k])
        head = prev;
    }
    return path;
}
var map = [[true, true, true],
[false, false, true],
[true, true, true]];
console.log(solve(map, { x: 0, y: 0 }, { x: 2, y: 0 }))